package org.goface.rpc.invoker;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.goface.rpc.RPC;

public class SpringBeanInvoker implements ServiceInvoker {
    private Map<String, BeanCache> beanCaches = new ConcurrentHashMap<>();

    @Override
    public Object invork(Object... args) throws Throwable {
        String serviceName = (String) args[0];
        String operatorName = (String) args[1];
        Class<?>[] argsType = (Class<?>[]) args[2];
        Object[] serviceArgs = (Object[]) args[3];
        BeanCache serviceBean = getBeanInstance(serviceName);
        Method method = serviceBean.getMethod(operatorName, argsType);
        Object retValue = null;
        retValue = method.invoke(serviceBean.beanInstance, serviceArgs);
        return retValue;
    }

    private BeanCache getBeanInstance(String serviceName) {
        BeanCache beanInstanceCache = beanCaches.get(serviceName);
        if (beanInstanceCache == null) {
            Object serviceBean = RPC.getBean(serviceName);
            beanInstanceCache = new BeanCache(serviceBean);
            beanCaches.put(serviceName, beanInstanceCache);
        }
        return beanInstanceCache;

    }

}
